bitkeeper revision 1.1159.79.13 (4151745aQFYQyiyDcwHh4KsbytECJg)
authorcl349@freefall.cl.cam.ac.uk <cl349@freefall.cl.cam.ac.uk>
Wed, 22 Sep 2004 12:47:22 +0000 (12:47 +0000)
committercl349@freefall.cl.cam.ac.uk <cl349@freefall.cl.cam.ac.uk>
Wed, 22 Sep 2004 12:47:22 +0000 (12:47 +0000)
Fix time.

netbsd-2.0-xen-sparse/sys/arch/xen/conf/XEN
netbsd-2.0-xen-sparse/sys/arch/xen/xen/clock.c

index 2fbb9998ac3b84e9edbf399360e621c575d462db..e54802263f2196c315968b576578211a2a7cc3ad 100644 (file)
@@ -13,7 +13,6 @@ maxusers      32              # estimated number of users
 #
 options                XEN
 #options               DOM0OPS
-options                HZ=50
 
 #options       I586_CPU
 options        I686_CPU
index 6783f69363f2b674c5a7600240bf7d25c3920c4b..fa7d986eb9b85a4a94c27a3a0f17171f144ef699 100644 (file)
@@ -54,13 +54,17 @@ __KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.1.2.2 2004/07/17 16:43:56 he Exp $");
 static int xen_timer_handler(void *, struct trapframe *);
 
 /* These are peridically updated in shared_info, and then copied here. */
-static unsigned long shadow_tsc_stamp;
-static u_int64_t shadow_system_time;
+static uint64_t shadow_tsc_stamp;
+static uint64_t shadow_system_time;
 static unsigned long shadow_time_version;
 static struct timeval shadow_tv;
 
 static int timeset;
 
+static uint64_t processed_system_time;
+
+#define NS_PER_TICK (1000000000ULL/hz)
+
 /*
  * Reads a consistent set of time-base values from Xen, into a shadow data
  * area.  Must be called at splclock.
@@ -79,6 +83,16 @@ get_time_values_from_xen(void)
        } while (shadow_time_version != HYPERVISOR_shared_info->time_version1);
 }
 
+static uint64_t
+get_tsc_offset_ns(void)
+{
+       uint32_t tsc_delta;
+       struct cpu_info *ci = curcpu();
+
+       tsc_delta = cpu_counter32() - shadow_tsc_stamp;
+       return tsc_delta * 1000000000 / cpu_frequency(ci);
+}
+
 void
 inittodr(time_t base)
 {
@@ -190,6 +204,9 @@ xen_initclocks()
 {
        int irq = bind_virq_to_irq(VIRQ_TIMER);
 
+       get_time_values_from_xen();
+       processed_system_time = shadow_system_time;
+
        event_set_handler(irq, (int (*)(void *))xen_timer_handler,
            NULL, IPL_CLOCK);
        hypervisor_enable_irq(irq);
@@ -198,6 +215,8 @@ xen_initclocks()
 static int
 xen_timer_handler(void *arg, struct trapframe *regs)
 {
+       int64_t delta;
+
 #if defined(I586_CPU) || defined(I686_CPU)
        static int microset_iter; /* call cc_microset once/sec */
        struct cpu_info *ci = curcpu();
@@ -223,7 +242,13 @@ xen_timer_handler(void *arg, struct trapframe *regs)
 
        get_time_values_from_xen();
 
-       hardclock((struct clockframe *)regs);
+       delta = (int64_t)(shadow_system_time + get_tsc_offset_ns() -
+                         processed_system_time);
+       while (delta >= NS_PER_TICK) {
+               hardclock((struct clockframe *)regs);
+               delta -= NS_PER_TICK;
+               processed_system_time += NS_PER_TICK;
+       }
 
        return 0;
 }